﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
namespace ControlsTool.Controls
{
    public partial class TreeComboBox : ComboBox
    {
        private const int WM_LBUTTONDOWN = 0x201, WM_LBUTTONDBLCLK = 0x203;
        ToolStripControlHost treeViewHost;
        ToolStripDropDown dropDown;
        ICollection data;
        List<TreeNode> TreeNodes;


        public string EnabledMember { get; set; }
        public TreeComboBox()
        {
            TreeView treeView = new TreeView();
            treeView.AfterSelect += new TreeViewEventHandler(treeView_AfterSelect);
            treeView.BorderStyle = BorderStyle.None;

            treeViewHost = new ToolStripControlHost(treeView);
            dropDown = new ToolStripDropDown();
            dropDown.Width = this.Width;
            dropDown.Items.Add(treeViewHost);
        }

        public void treeView_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (TreeView.SelectedNode.Nodes.Count == 0)
            {
                this.Text = TreeView.SelectedNode.Text;
                dropDown.Close();
            }
        }
        public TreeView TreeView
        {
            get { return treeViewHost.Control as TreeView; }
        }
        private void ShowDropDown()
        {
            if (dropDown != null)
            {
                treeViewHost.Size = new Size(DropDownWidth - 2, DropDownHeight);
                dropDown.Show(this, 0, this.Height);

            }
        }
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_LBUTTONDBLCLK || m.Msg == WM_LBUTTONDOWN)
            {
                ShowDropDown();
                return;
            }
            base.WndProc(ref m);
        }

        public string ImageMember { get; set; }

        public string NodesMember { get; set; }

        public new object DataSource
        {
            get
            {
                return data;
            }
            set
            {
                data = value as ICollection;
                TreeNodes = new List<TreeNode>();
                BindingTree();
            }
        }


        public void BindingTree()
        {
            this.Items.Clear();
            TreeView.Nodes.Clear();
            if (data == null)
                return;

            if (string.IsNullOrEmpty(DisplayMember))
                return;

            if (data == null || data.Count == 0)
                return;
            Type type = null;
            PropertyInfo[] propertyInfos = null;
            PropertyInfo info = null;
            foreach (var item in data)
            {
                if (type == null)
                {
                    type = item.GetType();
                    propertyInfos = type.GetProperties();
                    info = propertyInfos.FirstOrDefault(p => p.Name == NodesMember);
                }
                TreeNode childNode = GetTreeNode(item, propertyInfos, info);
                if (childNode != null)
                    TreeView.Nodes.Add(childNode);
            }
            foreach (var item in TreeNodes)
                Items.Add(item.Text);
        }

        public new object SelectedItem
        {
            get { return data != null ? TreeView.SelectedNode?.Tag : TreeView.SelectedNode; }
        }

        public int SelectedIndexTree
        {

            get
            {
                if (TreeView.SelectedNode == null)
                    return -1;
                if (data == null || data.Count == 0)
                    return -1;
                return TreeNodes.IndexOf(TreeView.SelectedNode);
            }
            set
            {
                if (data == null)
                    return;
                TreeView.AfterSelect -= new TreeViewEventHandler(treeView_AfterSelect);
                if (value < 0 || value > TreeNodes.Count - 1)
                {
                    TreeView.SelectedNode = null;
                    this.Text = "";
                }
                else
                {
                    this.Text = TreeNodes[value].Text;
                    TreeView.SelectedNode = TreeNodes[value];
                }
                TreeView.AfterSelect += new TreeViewEventHandler(treeView_AfterSelect);

            }
        }

        private TreeNode GetTreeNode(object obj, PropertyInfo[] propertyInfos, PropertyInfo pinfo)
        {
            TreeNode node = new TreeNode();
            node.Text = propertyInfos.FirstOrDefault(p => p.Name == DisplayMember)?.GetValue(obj, null)?.ToString();
            node.Tag = obj;

            if (!string.IsNullOrEmpty(EnabledMember))
            {
                string enabledtext = propertyInfos.FirstOrDefault(p => p.Name == EnabledMember)?.GetValue(obj, null)?.ToString();
                if (!string.IsNullOrEmpty(enabledtext) && enabledtext == "False")
                    node.ForeColor = Color.Gray;
            }

            //node.NodeFont= new Font()

            if (pinfo == null)
                return node;

            ICollection collection = (ICollection)pinfo.GetValue(obj, null);
            if (collection == null || collection.Count == 0)
                TreeNodes.Add(node);
            else
            {
                foreach (var item in collection)
                {
                    TreeNode childNode = GetTreeNode(item, propertyInfos, pinfo);
                    if (childNode != null)
                        node.Nodes.Add(childNode);
                }
            }
            return node;
        }
    }
}
